package com.tsf.hbase.config;

import com.tsf.hbase.HBaseClientFactory;
import com.tsf.hbase.HBaseTemplate;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PreDestroy;

/**
 * hbase自动注入配置类
 *
 * @author taoningbo
 * @since 1.0
 */
@Configuration
@ConditionalOnClass({Connection.class, Admin.class, HTableDescriptor.class, HColumnDescriptor.class})
@EnableConfigurationProperties(HBaseProperties.class)
public class HBaseAutoConfiguration {

    /**
     * hbase connection auto configuration.
     */
    @Configuration
    protected static class HBaseClientConfiguration {

        private final HBaseProperties properties;

        public HBaseClientConfiguration(HBaseProperties properties) {
            this.properties = properties;
        }

        @Bean
        @ConditionalOnMissingBean(HBaseClientFactory.class)
        public HBaseClientFactory hBaseClientFactory() {
            return new HBaseClientFactory(properties);
        }
    }

    /**
     * hbase template auto configuration.
     */
    @Configuration
    @AutoConfigureAfter(HBaseClientConfiguration.class)
    protected static class HBaseTemplateConfiguration {

        private final HBaseClientFactory factory;

        public HBaseTemplateConfiguration(HBaseClientFactory factory) {
            this.factory = factory;
        }

        @Bean
        @ConditionalOnMissingBean(HBaseTemplate.class)
        public HBaseTemplate hBaseTemplate() {
            return new HBaseTemplate(factory);
        }

        @PreDestroy
        public final void preDestroy() {
            if (factory != null) {
                factory.destroy();
            }
        }
    }
}
